package com.lznb.cloud.service.impl;

import com.lznb.cloud.entity.News;
import com.lznb.cloud.entity.NewsCategory;
import com.lznb.cloud.repository.NewsCategoryRepository;
import com.lznb.cloud.service.NewsCategoryService;
import com.lznb.cloud.service.NewsService;
import com.lznb.cloud.utils.JsonResultExt;
import com.lznb.cloud.utils.SQLUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
@CacheConfig(cacheNames="newsCategory")
public class NewsCategoryServiceImpl implements NewsCategoryService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private NewsCategoryRepository newsCategoryRepository;

    @Autowired
    private NewsService newsService;


    @Override
    @CachePut(key = "#root.caches[0].name + ':' + #p0")
    public NewsCategory getNewsCategory(String categoryId) {

        return newsCategoryRepository.findOne(categoryId);
    }

    @Override
    public JsonResultExt save(NewsCategory newsCategory) {
        JsonResultExt jsonResultExt=new JsonResultExt();
        newsCategoryRepository.save(newsCategory);
        return jsonResultExt;
    }

    @Override
    @CachePut( key = "#root.caches[0].name + ':' + #p0.categoryId")
    public JsonResultExt update(NewsCategory newsCategory) {
        JsonResultExt jsonResultExt=new JsonResultExt();
        jsonResultExt.run(jsonResultExt, newsCategoryRepository.saveAndFlush(newsCategory));
        return jsonResultExt;
    }

    @Override
    @CacheEvict(key = "#root.caches[0].name + ':' + #p0")
    public JsonResultExt delete(String categoryId) {
        JsonResultExt jsonResultExt=new JsonResultExt();
        //根据父栏目查询栏目，所删除的栏目ID为查询条件，即父栏目ID
        List<NewsCategory> newsCategoryList=newsCategoryRepository.findByCategoryPid(categoryId);
        if(newsCategoryList!=null&&newsCategoryList.size()>1){
            jsonResultExt.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResultExt.setMessage("该栏目下有子栏目，请先删除子栏目！");
            return jsonResultExt;
        }
        List<News> newsList = newsService.findByCategory(categoryId);
        if(newsList!=null&&newsList.size()!=0){
            jsonResultExt.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
            jsonResultExt.setMessage("该栏目下有新闻，请先删除新闻！");
            return jsonResultExt;
        }

        newsCategoryRepository.delete(categoryId);
        jsonResultExt.setCode(HttpStatus.OK.value());
        jsonResultExt.setMessage("删除成功！");
        return jsonResultExt;
    }

    @Override
    public Map findByPage(Integer pageIndex, Integer size,NewsCategory newsCategory,Map<String,String> condition) {
        Sort sort = new Sort(Sort.Direction.DESC, "categoryPid");
        Pageable pageable = new PageRequest(pageIndex, size, sort);
        Specification<NewsCategory> specification = this.handleSpeci(newsCategory,condition);
        Page<NewsCategory> list = newsCategoryRepository.findAll(specification,pageable);
        Map map=new HashMap();
        map.put("code",0);
        map.put("msg","");
        map.put("count",list.getTotalElements());
        map.put("data",list.getContent());
        Iterator<NewsCategory> newsCategoryIterator = list.getContent().iterator();
        while (newsCategoryIterator.hasNext()){
            NewsCategory category = newsCategoryIterator.next();
            String categoryPid = category.getCategoryPid();

            NewsCategory one = newsCategoryRepository.findOne(categoryPid);
            category.setCategoryPid(one.getCategoryName());
        }
        return map;
    }

    @Override
    public List<NewsCategory> findAll() {
        return  newsCategoryRepository.findAll();
    }


    /***
    * 考查询条件处理<br>
    * @param newsCategory {@link NewsCategory} 查询条件实体
    * @return {@link Specification}
    */
    public Specification<NewsCategory> handleSpeci(NewsCategory newsCategory,Map<String,String> condition) {
        Specification<NewsCategory> specification = new Specification<NewsCategory>() {
            @Override
            public Predicate toPredicate(Root<NewsCategory> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = SQLUtils.CriteriaSQLExt(root,newsCategory,criteriaBuilder,condition);
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return specification;
    }
}
